package algo3.algothief.modelo;

import java.util.ArrayList;
import java.util.Random;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;


public class Pista {
	
	private String pistaFacilInicial;
	private String pistaMediaInicial;
	private String pistaDificilInicial;
	
	private ArrayList<String> pistasFaciles;
	private ArrayList<String> pistasMedias;
	private ArrayList<String> pistasDificiles;
	
	private static String pistaNula = "";
	
//-------------------------------------------------------------------------------------
	
	public Pista(String pistaFacil, String pistaMedia, String pistaDificil){
        this.pistaFacilInicial = pistaFacil;
        this.pistaMediaInicial = pistaMedia;
        this.pistaDificilInicial = pistaDificil; 

		this.pistasFaciles = new ArrayList<String>();
		this.pistasMedias = new ArrayList<String>();
		this.pistasDificiles = new ArrayList<String>();
	}
	
//-------------------------------------------------------------------------------------	
	
	// El String descripcionDelOrigen tiene la capital del pais, y el lugar de dicho pais.
	
	// La forma de serializar esta escrita lo mas generica posible.
	public Element serializar(Document doc, String descripcionDelOrigen) {
		Element elementoPista = doc.createElement("Pistas" + descripcionDelOrigen);
		
		this.agregarPistasIniciales(elementoPista, doc);
		
		Element elementoPistasFaciles = doc.createElement("PistasFaciles");
		Element elementoPistasMedias = doc.createElement("PistasMedias");
		Element elementoPistasDificiles = doc.createElement("PistasDificiles");
		elementoPista.appendChild(elementoPistasFaciles);
		elementoPista.appendChild(elementoPistasMedias);
		elementoPista.appendChild(elementoPistasDificiles);
			
		this.agregarPistas(elementoPistasFaciles, pistasFaciles, doc);
		this.agregarPistas(elementoPistasMedias, pistasMedias, doc);
		this.agregarPistas(elementoPistasDificiles, pistasDificiles, doc);
			
		return elementoPista;
	}
	
	public static Pista hidratar(Document doc, String descripcionDelOrigen) {
		Element elementoPista = (Element)doc.getElementsByTagName("Pistas" + descripcionDelOrigen).item(0);

		String[] pistasIniciales = Pista.obtenerPistasIniciales(elementoPista);
		String pistaFacil = pistasIniciales[0];
		String pistaMedia = pistasIniciales[1];
		String pistaDificil = pistasIniciales[2];
		
		Element elementoPistasFaciles = (Element)elementoPista.getElementsByTagName("PistasFaciles").item(0);
		ArrayList<String> pistasFaciles = Pista.obtenerPistas(elementoPistasFaciles);
			
		Element elementoPistasMedias = (Element)elementoPista.getElementsByTagName("PistasFaciles").item(0);
		ArrayList<String> pistasMedias = Pista.obtenerPistas(elementoPistasMedias);
		
		Element elementoPistasDificiles = (Element)elementoPista.getElementsByTagName("PistasFaciles").item(0);
		ArrayList<String> pistasDificiles = Pista.obtenerPistas(elementoPistasDificiles);
		
		Pista pistaNueva = new Pista(pistaFacil, pistaMedia, pistaDificil);
		pistaNueva.modificarPistasFaciles(pistasFaciles);
		pistaNueva.modificarPistasMedias(pistasMedias);
		pistaNueva.modificarPistasDificiles(pistasDificiles);
		
		return pistaNueva;
	}
		
//-------------------------------------------------------------------------------------	
	
	private void agregarPistasIniciales(Element elementoPistas, Document doc) {
		Element elementoPistaFacilInicial = doc.createElement("PistaFacilInicial");
		Element elementoPistaMediaInicial = doc.createElement("PistaMediaInicial");
		Element elementoPistaDificilInicial = doc.createElement("PistaDificilInicial");
		elementoPistaFacilInicial.setAttribute("contenido", pistaFacilInicial);
		elementoPistaMediaInicial.setAttribute("contenido", pistaMediaInicial);
		elementoPistaDificilInicial.setAttribute("contenido", pistaDificilInicial);
		
		elementoPistas.appendChild(elementoPistaFacilInicial);
		elementoPistas.appendChild(elementoPistaMediaInicial);
		elementoPistas.appendChild(elementoPistaDificilInicial);
	}
	
	private void agregarPistas(Element elementoPistas, ArrayList<String> pistas, Document doc) {
		for (String pista : pistas) {
			Element elementoPista = doc.createElement("Pista");
			elementoPista.setAttribute("contenido", pista);
			
			elementoPistas.appendChild(elementoPista);
		}
	}
	
	
	
	private static String[] obtenerPistasIniciales(Element elementoPista) {
		Element elementoPistaFacilInicial = (Element)elementoPista.getElementsByTagName("PistaFacilInicial").item(0);
		Element elementoPistaMediaInicial = (Element)elementoPista.getElementsByTagName("PistaMediaInicial").item(0);
		Element elementoPistaDificilInicial = (Element)elementoPista.getElementsByTagName("PistaDificilInicial").item(0);
		String pistaFacil = elementoPistaFacilInicial.getAttribute("contenido");
		String pistaMedia = elementoPistaMediaInicial.getAttribute("contenido");
		String pistaDificil = elementoPistaDificilInicial.getAttribute("contenido");
		
		String[] pistasIniciales = { pistaFacil, pistaMedia, pistaDificil };
		
		return pistasIniciales;
	}
	
	private static ArrayList<String> obtenerPistas(Element elementosPistasDeAlgunaCategoria) {
		ArrayList<String> pistas = new ArrayList<String>();
		
		NodeList elementosPistas = elementosPistasDeAlgunaCategoria.getElementsByTagName("Pista");
		int cantidadDePistas = elementosPistas.getLength();
		
		for (int i = 0; i < cantidadDePistas; i++) {
			String contenidoDeLaPista = ((Element)elementosPistas.item(i)).getAttribute("contenido");
			pistas.add(contenidoDeLaPista);
		}
		
		return pistas;
	}
	
	private void modificarPistasFaciles(ArrayList<String> pistasFacilesNuevas) {
		this.pistasFaciles = pistasFacilesNuevas;
	}
	
	private void modificarPistasMedias(ArrayList<String> pistasMediasNuevas) {
		this.pistasMedias = pistasMediasNuevas;
	}
	
	private void modificarPistasDificiles(ArrayList<String> pistasDificilesNuevas) {
		this.pistasDificiles = pistasDificilesNuevas;
	}
	
	
	
	private int generarEnteroAlAzarEntre(int minimoValor, int maximoValor) {
		Random generadorAleatorio = new Random();
		int numeroAlAzar = generadorAleatorio.nextInt(maximoValor - minimoValor + 1) + minimoValor;
	
		return numeroAlAzar;
	}
	
//-------------------------------------------------------------------------------------		
	
	public ArrayList<String> verPistasFaciles() {
		return this.pistasFaciles;
	}
	
	public ArrayList<String> verPistasMedias() {
		return this.pistasMedias;
	}
	
	public ArrayList<String> verPistasDificiles() {
		return this.pistasDificiles;
	}
	
	public String obtenerPistaFacil() {
		boolean pistaFacilIgualALaPistaNula = pistaFacilInicial.matches(pistaNula);
		if (!pistaFacilIgualALaPistaNula) return this.pistaFacilInicial;
		
		int cantidadDePistasFaciles = pistasFaciles.size();
		int indiceDeUnaPistaAlAzar = this.generarEnteroAlAzarEntre(0, cantidadDePistasFaciles-1);
		return pistasFaciles.get(indiceDeUnaPistaAlAzar);
	}
	
	public String obtenerPistaMedia() {
		boolean pistaMediaIgualALaPistaNula = pistaMediaInicial.matches(pistaNula);
		if (!pistaMediaIgualALaPistaNula) return this.pistaMediaInicial;

		int cantidadDePistasMedias = pistasMedias.size();
		int indiceDeUnaPistaAlAzar = this.generarEnteroAlAzarEntre(0, cantidadDePistasMedias-1);
		return pistasMedias.get(indiceDeUnaPistaAlAzar);
	}
	
	public String obtenerPistaDificil() {
		boolean pistaDificilIgualALaPistaNula = pistaDificilInicial.matches(pistaNula);
		if (!pistaDificilIgualALaPistaNula) return this.pistaDificilInicial;

		int cantidadDePistasDificiles = pistasDificiles.size();
		int indiceDeUnaPistaAlAzar = this.generarEnteroAlAzarEntre(0, cantidadDePistasDificiles-1);
		return pistasDificiles.get(indiceDeUnaPistaAlAzar);
	}
	
	public void agregarPistaDeLadron(String pista) {
		ArrayList<String> nuevasPistas = new ArrayList<String>();
		for (String pistaActual : pistasFaciles) 
			nuevasPistas.add(pistaActual + ". " + pista);
		
		this.pistasFaciles = nuevasPistas;
		
		nuevasPistas = new ArrayList<String>();
		for(String pistaActual : pistasMedias) 
			nuevasPistas.add(pistaActual + ". " + pista);
		
		this.pistasMedias = nuevasPistas;
		
		nuevasPistas = new ArrayList<String>();
		for(String pistaActual : pistasDificiles) 
			nuevasPistas.add(pistaActual + ". " + pista);
		
		this.pistasDificiles = nuevasPistas;
		
	}
}
